/*
 * Partido.java
 *
 * Created on 16 de julio de 2006, 1:41
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package futbol;

import futbol.tacticas.Comando;
import futbol.tacticas.SituacionJugadores;
import futbol.tacticas.concursantes.Concursantes;
import futbol.tacticas.concursantes.Tactica;
import futbol.tacticas.concursantes2007.TacticaDemo01;
import futbol.tacticas.concursantes.TacticaVacia;

import java.awt.Color;
import java.awt.Point;
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Date;
import java.util.Vector;

/**
 *
 * @author Administrador
 */
public class Partido {
    
    private static final int LOG_SIN_LOG = 0;
    private static final int LOG_EJECUTAR_Y_GRABAR = 1;
    private static final int LOG_REPRODUCIR = 2;
    
    private Tactica tacticas[]=new Tactica[2];
    private Equipo equipos[]=new Equipo[2];
    private Bola bola=new Bola();
    private int nPuntos[]=new int[2];
    private int nGanador=-1;
    private long nPosicionBolaParaEmpate=0;  //Se va sumando la posicion de la bola para en caso de empate el que mas haya acercado la bola a la portera contraria gane.
    
    private int nUltimaJugadaHuboGol = -1; //-1 no hubo gol, 0 hubo gol equipo A, 1 hubo gol equipo B

    //Almacenamiento de la partida: By Ismael Marical
    private RandomAccessFile ficheroLog;
    private int nTipoPartida = 0;  //0-Ejecucion, 1-Ejecucin y Grabacin, 2-Reproduccin partida grabada.
    
    public Partido(){  
        this.nTipoPartida=LOG_SIN_LOG;
        setTacticas(Concursantes.getTacticas()[0],Concursantes.getTacticas()[1]);
        posicionarJugadoresSaqueCentro();
    }
    
    public Partido(String fichero)
    {
        this.nTipoPartida=LOG_REPRODUCIR;
        this.jvcAbrirFichero(fichero);  //Abre el fichero donde se almacena la partida.
        jvcLeerNombres();
        posicionarJugadoresSaqueCentro();
    }
    
    public Partido(Tactica t1, Tactica t2){
        this.nTipoPartida=LOG_SIN_LOG;
        setTacticas(t1,t2);
        posicionarJugadoresSaqueCentro();
    }
    
    public Partido(Tactica t1, Tactica t2, String fichero){
        this.nTipoPartida=LOG_EJECUTAR_Y_GRABAR;
        setTacticas(t1,t2);
        jvcAbrirFichero(fichero);
        jvcEscribirNombres();
        posicionarJugadoresSaqueCentro();
    }
    
    public void setTacticas(Tactica t1, Tactica t2){
        tacticas[0]=t1;
        tacticas[1]=t2;
        equipos[0]=new Equipo(tacticas[0]);
        equipos[1]=new Equipo(tacticas[1]);
    }

    public Equipo getEquipo(int n){
        return equipos[n];
    }
    
    public Tactica getTactica(int n){
        return tacticas[n];
    }

    public Bola getBola(){
        return bola;
    }
    
    public int getFactor(int nEquipo){
        if (nEquipo==0) return 1;
        else return -1;
    }
    
    public long getPosicionBolaParaEmpate(){
        return nPosicionBolaParaEmpate;
    }
    
    public void mover(){
        nUltimaJugadaHuboGol=-1;  //Se inicializa que no hay gol.
        if (nTipoPartida!=LOG_REPRODUCIR){
            for (int n=0;n<2;n++)
                equipos[n].mover();
            bola.mover();
            ejecutarTacticas();
            nUltimaJugadaHuboGol=bola.esGol();  //Se modifica segn si ha habido gol.
            if (nTipoPartida == LOG_EJECUTAR_Y_GRABAR)
                jvcEscribirPosicion();
        }else{
            jvcLeerPosicion();
        }
        if (nUltimaJugadaHuboGol!=-1){
            nPuntos[nUltimaJugadaHuboGol]++;
            posicionarJugadoresSaqueCentro();
            bola.setXY(0,0);
            bola.reserSistemaAntibloqueo();
            equipos[1-nUltimaJugadaHuboGol].getJugador(10).setXY(0,0);
        }
        nPosicionBolaParaEmpate+=bola.getX()/10; //Suma la posicin de la bola
    }
    
    public int getUltimaJugadaHuboGol(){
        return nUltimaJugadaHuboGol;
    }
    
    public SituacionJugadores getSituacionJugadores(int nEquipo){
        int f=getFactor(nEquipo);
        return new SituacionJugadores(
                equipos[nEquipo].getPoints(f),
                equipos[1-nEquipo].getPoints(f),
                bola.getPoint(f)
                );
    }
    
    private void posicionarJugadoresSaqueCentro(){
        if (nTipoPartida!=LOG_REPRODUCIR){
            for (int n=0;n<2;n++){
                int f=getFactor(n);
                for (int m=0;m<11;m++){
                    Jugador j=equipos[n].getJugador(m);
                    double x=(General.control(tacticas[n].getXInicial(m),-160,160)-160)/2;
                    double y=tacticas[n].getYInicial(m);
                    for (int z=0;z<10;z++)
                        if (General.getDistancia(0,0,x,y)<60)
                            x-=10;
                    j.setXY(x*f,y*f);
                }
            }
            if (nTipoPartida==LOG_EJECUTAR_Y_GRABAR)
                jvcEscribirPosicion();
        }else
            jvcLeerPosicion();
    }
    
    public void ejecutarTacticas(){
        //Paso 1. Se obtienen todos los comandos de las dos tcticas
        Vector<Comando> vComandos[]=new Vector[2];
        for (int nEquipo=0;nEquipo<2;nEquipo++){
        	try{
        		vComandos[nEquipo] = tacticas[nEquipo].getComandos(getSituacionJugadores(nEquipo));
        	}catch(Exception e){
        		vComandos[nEquipo] = new Vector();
        	}
        }
        
        //Paso 2. Se almacenan en un ArrayList todos los jugadores
        ArrayList<Integer> alJugadores=new ArrayList();
        for (int nEquipo=0;nEquipo<2;nEquipo++)
            for (int nJugador=0;nJugador<11;nJugador++)
                alJugadores.add(new Integer(nJugador*10+nEquipo)); // Unidades equipo a partir de decenas el jugador --> Ejemplo: 81. Jugador 8 del equipo 1

        //Paso 3. Se van obteniendo los jugadores del arraylist en orden aleatorio y se ejecutan sus comandos
        int nPosAleatorio, nEquipo, nJugador, nValor;
        while(alJugadores.size()>0){
            nPosAleatorio=(int)(Math.random()*alJugadores.size());
            nValor=alJugadores.get(nPosAleatorio);  //Lee el jugador
            alJugadores.remove(nPosAleatorio);
            nJugador = nValor/10;
            nEquipo = nValor%10;
            for (Comando comAux:vComandos[nEquipo])
                if (nJugador==comAux.getJugador()){
                    comAux.setEquipo(nEquipo); //Modificamos el valor del Equipo para que nadie intente lanzar comandos del otro equipo.
                    comAux.ejecutar(this);
                }
        }
    }
    
    public int getPuntos(int n){
        return nPuntos[n];
    }
    
    public int getGanador(){
        if (nGanador!=-1) return nGanador;
        if (nPuntos[0]>nPuntos[1]) return 0;
        if (nPuntos[0]<nPuntos[1]) return 1;
        if (nPosicionBolaParaEmpate>0) return 0;
        if (nPosicionBolaParaEmpate<0) return 1;
        nGanador=(int)(Math.random()*2);
        return nGanador;
    }
    
    public void acabar(){
        if (nTipoPartida!=LOG_SIN_LOG)
            jvcCerrarFichero();
    }

    //****************************************************************
    //*                                                              *
    //*      ALMACENAMIENTO Y REPRODUCCION By Ismael Marical         *
    //*                                                              *
    //****************************************************************
    
    private void jvcAbrirFichero(String fichero){
        try
        {
            ficheroLog = new RandomAccessFile(fichero, "rw");
            //Guarda informacin de los equipos
        }
        catch (IOException e) {
            e.printStackTrace();  //Si no puede abrir el fichero muestra el error, pero la partida continua.
        }
    }
    
    private void jvcCerrarFichero(){
        try
        {
            ficheroLog.close();
        }
        catch (IOException e) {
        }
    }    

    private void jvcEscribirNombres()
    {
        try{
            for (int n=0;n<2;n++){
                ficheroLog.writeUTF(tacticas[n].getNombre());
                ficheroLog.writeInt(tacticas[n].getColor1().getRGB());
                ficheroLog.writeInt(tacticas[n].getColor2().getRGB());
                ficheroLog.writeInt(tacticas[n].getColorNumero().getRGB());
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    private void jvcLeerNombres()
    {
        try{
            Tactica t[]=new Tactica[2];
            for (int n=0;n<2;n++){
                String sNombre=ficheroLog.readUTF();
                Color c1=new Color(ficheroLog.readInt());
                Color c2=new Color(ficheroLog.readInt());
                Color cN=new Color(ficheroLog.readInt());
                t[n]=new TacticaVacia(sNombre,c1,c2,cN);
            }
            setTacticas(t[0],t[1]);
        }catch(Exception e){
            e.printStackTrace();
        }
    }    
    
    private void jvcLeerPosicion()
    {
        short x, y;
        try
        {
            for (int n = 0; n < 2; n++)
                for (int i = 0; i < 11; i++)
                    equipos[n].getJugador(i).setXY(ficheroLog.readShort(), ficheroLog.readShort());
            bola.setXY(ficheroLog.readShort(), ficheroLog.readShort());
            bola.setGolpeada(ficheroLog.readByte());
            nPosicionBolaParaEmpate = ficheroLog.readLong();
            int fuerzaGolpeo = ficheroLog.readByte();  //Fuerza de golpeo de Baln
            nUltimaJugadaHuboGol = ficheroLog.readByte();
        } 
        catch (EOFException e)
        {
            e.printStackTrace();
        }
        catch (IOException e2) {
            e2.printStackTrace();
        }
    }
    
    private void jvcEscribirPosicion()
    {
        Point p[];
        try
        {
            for (int n = 0; n < 2; n++)
            {
                p = equipos[n].getPoints(1);
                for (int i = 0; i < 11; i++)
                {
                    ficheroLog.writeShort(p[i].x);
                    ficheroLog.writeShort(p[i].y);
                }
            }
            ficheroLog.writeShort((int)bola.getX());
            ficheroLog.writeShort((int)bola.getY());
            ficheroLog.writeByte((byte)bola.getGolpeada());
            ficheroLog.writeLong(nPosicionBolaParaEmpate);
            ficheroLog.writeByte(0);  //Fuerza de golpeo de Baln
            ficheroLog.writeByte(nUltimaJugadaHuboGol);
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }
}
